package main

import (
	"fmt"
	"go.uber.org/zap"
	"laxkits/lib/laxproxy"
	"laxkits/lib/laxutils"
	"strings"
	"time"
)

// @Desc: xml配置的协议信息
type ROProtoNode struct {
	Name        string `xml:"Name"`
	LowerName   string
	ProtoId     uint32        `xml:"ProtoId"`
	ArgName     string        `xml:"Arg"`
	ResName     string        `xml:"Res"`
	PtcDataName string        `xml:"MemberType"`
	Timeout     time.Duration `xml:"timeout"`
}

// / protocol.xml
type ROProtoPTCXML struct {
	PtcNodes []ROProtoNode `xml:"PGProtocol"`
}

// rpc.xml
type ROProtoRPCXML struct {
	RpcNodes []ROProtoNode `xml:"PGRpc"`
}

// 全局唯一管理器
type ROProtocolsMgr struct {
	ptcXmlList ROProtoPTCXML
	rpcXmlList ROProtoRPCXML

	// 协议id对应的具体信息   <protoid, node>
	id2Node map[uint32]ROProtoNode
}

// 全局唯一协议管理
var globalROProtoMgr = ROProtocolsMgr{}

func GetProtoNode(protoId uint32) *ROProtoNode {
	if node, ok := globalROProtoMgr.id2Node[protoId]; ok {
		return &node
	}
	return nil
}

// 加载文件之后,初始化好数据
func (mgr *ROProtocolsMgr) afterLoad() bool {
	mgr.id2Node = make(map[uint32]ROProtoNode)
	for _, node := range mgr.ptcXmlList.PtcNodes {
		node.LowerName = strings.ToLower(node.Name)
		mgr.id2Node[node.ProtoId] = node
		if (node.ProtoId>>24) == 'C' && len(node.PtcDataName) > 0 && ((node.ProtoId>>16)&0xFF) != 'I' {
			wholeName := fmt.Sprintf("Ptc%c2%c_%s", node.ProtoId>>24, (node.ProtoId>>16)&0xFF, node.Name)
			laxproxy.RegisterClientProtocol(laxproxy.ClientProtocolNode{
				ProtoId:   node.ProtoId,
				ProtoName: wholeName,
				ProtoArg:  "KKSG." + node.PtcDataName,
				Timeout:   0,
			})
		}
	}
	for _, node := range mgr.rpcXmlList.RpcNodes {
		node.LowerName = strings.ToLower(node.Name)
		mgr.id2Node[node.ProtoId] = node
		if (node.ProtoId>>24) == 'C' && len(node.ArgName) > 0 && ((node.ProtoId>>16)&0xFF) != 'I' {
			wholeName := fmt.Sprintf("Rpc%c2%c_%s", node.ProtoId>>24, (node.ProtoId>>16)&0xFF, node.Name)
			laxproxy.RegisterClientProtocol(laxproxy.ClientProtocolNode{
				ProtoId:   node.ProtoId,
				ProtoName: wholeName,
				ProtoArg:  "KKSG." + node.ArgName,
				ProtoRes:  "KKSG." + node.ResName,
				Timeout:   node.Timeout,
			})
		}
	}
	return true
}

// @Desc: 解析协议xml文件
// @return bool 解析结果
func loadProtocolXML() bool {
	if err := laxutils.LoadXmlFile(globalXmlNode.ROProtoXMLPath+"protocol.xml", &globalROProtoMgr.ptcXmlList); err != nil {
		zap.S().Errorf("[协议] 解析protocol.xml出错[%v]", err)
		return false
	}
	if err := laxutils.LoadXmlFile(globalXmlNode.ROProtoXMLPath+"rpc.xml", &globalROProtoMgr.rpcXmlList); err != nil {
		zap.S().Errorf("[协议] 解析rpc.xml出错[%v]", err)
		return false
	}
	return globalROProtoMgr.afterLoad()
}
